#include <bits/stdc++.h>
using namespace std;

// #define ONLINE_JUDGE

#ifndef ONLINE_JUDGE
#define dbg(x...)                             \
	{                                         \
		cerr << "\033[32;1m" << #x << " -> "; \
		err(x);                               \
	}
void err()
{
	cerr << "\033[39;0m" << endl;
}
template <typename T, typename... A>
void err(T a, A... x)
{
	cerr << a << ' ';
	err(x...);
}
#else
#define dbg(...)
#endif

typedef long long LL;

const int N = 1e5 + 50;

typedef pair<int, int> P;

vector<P> a[N];

LL cp(P a, P b)
{
	return 1LL * a.first * b.second - 1LL * a.second * b.first;
}

typedef P P2;

int n, M;

struct L // k < 0
{
	P a, b;
	L(P a = P(0, 0), P b = P(0, 0))
		: a(a), b(b)
	{
		if (this->a > this->b)
			swap(this->a, this->b);
	}
	bool operator<(const L &other) const
	{
		P x = b - a, y = other.b - other.a;
		return cp(x, y) > 0;
	}
};

P operator-(const P &a, const P &b)
{
	return P(a.first - b.first, a.second - b.second);
}

vector<P> conv(vector<P> &a)
{
	sort(a.begin(), a.end());
	int x = a[0].first;
	int n = a.size();
	vector<P> res;
	res.push_back(a[0]);

	for (int i = 1; i < n; ++i)
	{
		if (res.back().second <= a[i].second)
			continue;
		while (res.size() >= 2 && cp(res.back() - res[res.size() - 2], a[i] - res[res.size() - 2]) <= 0)
			res.pop_back();
		res.push_back(a[i]);
	}
	return res;
}

struct L
{
	int first, second;
	L(int a, int b)
	{
		first = a;
		second = b;
		if (first < 0)
		{
			first = -first;
			second = -second;
		}
	}

	L(P p) : first(p.first), second(p.second) {}

	bool operator<(const L &other) const
	{
		LL c = 1LL * first * other.second - 1LL * second * other.first;
		return c > 0;
	}

	bool operator!=(const L &other) const
	{
		return first != other.first || second != other.second;
	}

	bool operator==(const L &other) const
	{
		return !(*this != other);
	}
};

bool check(L tar, LL &ans)
{
	int nowM = 0;
	ans = 0;
	LL x = 0;
	for (int i = 0; i < n; ++i)
	{
		auto p = lower_bound(b[i].begin(), b[i].end(), tar);
		// if (p == b[i].end() || (*p) != tar)
		// {
		int pos = p - b[i].begin();
		auto P = a[i][pos];
		nowM += P.first;
		ans += P.second;
		if (nowM > M)
			return false;
		// }

		if (p != b[i].end() && (*p) == tar)
		{
			x += p->first;
		}
	}

	x = min(x, (LL)M - nowM);
	// ans -= 
}

vector<L> dat, b[N];

int main(int argc, char const *argv[])
{

	scanf("%d%d", &n, &M);
	int m = 0;
	for (int i = 0; i < n; ++i)
	{
		int k;
		scanf("%d", &k);
		a[i].resize(k);
		for (int j = 0; j < k; ++j)
			scanf("%d%d", &a[i][j].first, &a[i][j].second);

		a[i] = conv(a[i]);
		m += a[i].size() - 1;
		b[i].resize(a[i].size() - 1);
		for (int j = 1; j < k; ++j)
		{
			b[i][j - 1] = a[i][j] - a[i][j - 1];
			dat.push_back(b[i][j - 1]);
		}

		for (auto p : a[i])
			dbg(i, p.first, p.second);
	}

	sort(dat.begin(), dat.end());

	return 0;
}